﻿using AIVision.Inspect.Halcon;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AIVision.Inspect.HCDL
{
   public  class DLInspect
    {
        public DLInspect(string processFilePath,string modelFilePath,HTuple dLDevice)
        {
            this.processFilePath = processFilePath;
            this.modelFilePath = modelFilePath;
            this.dLDevice = dLDevice;
        }
        private string processFilePath { get; set; } 
        private string modelFilePath { get; set; }
        private HTuple dLDevice;

        HTuple BatchSizeInference = 1;
        HTuple DLModelHandle = new HTuple();
        HTuple DLPreprocessParam = new HTuple();

        private HTuple classNames;
        public HTuple ClassNames { get => classNames; }

        private HTuple classIDs;
        public HTuple ClassIDs { get => classIDs;}

        private HTuple dLSampleBatch = new HTuple();
        public HTuple DLSampleBatch { get => dLSampleBatch; }

        private HTuple dLResultBatch = new HTuple();
        public HTuple DLResultBatch { get => dLResultBatch; }
        

        private HObject inferenceImage = new HObject();
        public HObject InferenceImage { get => inferenceImage; }

        private HObject segmentationImage = new HObject();
        public HObject SegmentationImage { get => segmentationImage;}

        private bool ConvertImage = false;

        
        public void Init()
        {
            DLModelHandle.Dispose();
            DLPreprocessParam.Dispose();

            using (HDevDisposeHelper dh = new HDevDisposeHelper())
            {
                HOperatorSet.SetSystem("cudnn_deterministic","true");
                HOperatorSet.ReadDlModel(modelFilePath, out DLModelHandle);
                HOperatorSet.SetDlModelParam(DLModelHandle, "batch_size", BatchSizeInference);
                HOperatorSet.SetDlModelParam(DLModelHandle, "device", dLDevice);
                HOperatorSet.ReadDict(processFilePath, null, null, out DLPreprocessParam);

                HOperatorSet.GetDictTuple(DLPreprocessParam, "class_names", out classNames);
                HOperatorSet.GetDictTuple(DLPreprocessParam, "class_ids", out classIDs);

                HTuple imageRangeMin = -127;
                HOperatorSet.GetDictTuple(DLPreprocessParam, "image_range_min", out imageRangeMin);
                if (imageRangeMin.I == 0)
                    ConvertImage = true;

            }
        }

        public void ExInspect(HObject img)
        {
            HObject defectRegion = new HObject();
         
            dLSampleBatch.Dispose();
            dLResultBatch.Dispose();
            defectRegion.Dispose();
            DLDatasetHelper.gen_dl_samples_from_images(img, out dLSampleBatch);
            DLPreprocessingHelper.preprocess_dl_samples(DLSampleBatch, DLPreprocessParam);
            HOperatorSet.ApplyDlModel(DLModelHandle, DLSampleBatch, "segmentation_image", out dLResultBatch);

            HOperatorSet.GetDictObject(out inferenceImage, DLSampleBatch, "image");
            if(ConvertImage)
                HOperatorSet.ConvertImageType(inferenceImage, out inferenceImage, "byte");
            HOperatorSet.GetDictObject(out segmentationImage, DLResultBatch, "segmentation_image");
        }

        public void Stop()
        {
            DLModelHandle = new HTuple();
            DLModelHandle.Dispose();
            DLPreprocessParam = new HTuple();
            DLPreprocessParam.Dispose();
        }
    }
}
